package com.asm.service;

import com.asm.dto.PageResult;
import com.asm.entity.sys.RoleAccess;
import com.asm.entity.sys.User;
import com.asm.repository.RoleAccessRepository;
import com.asm.repository.UserRepository;
import com.asm.util.Md5;
import com.asm.util.SnowflakeIdWorker;
import com.asm.vo.sys.RoleAccessVo;
import com.asm.vo.sys.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZhuangGuiMan
 */
@Service
public class UserService {

    @Resource
    private UserRepository userRepository;

    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    @Resource
    private RoleAccessRepository roleAccessRepository;

    @Resource
    private RoleAccessService roleAccessService;

    /**
     * 根据账号密码查询用户id
     *
     * @param account  账号
     * @param password 密码
     * @return 用户id
     */
    public Long getUserIdByAccountAndPassword(String account, String password) {
        User user = userRepository.findUserByAccountAndPasswordAndIsDel(account, password, false);
        if (user == null) {
            return -1L;
        }
        return user.getId();
    }

    /**
     * 获取所有用户信息
     *
     * @return 所有用户信息
     */
    public List<Map<String, Object>> findAllUsers() {
        return userRepository.findAllUsers();
    }

    /**
     * 根据角色代码查询用户信息
     *
     * @param roleCode 角色代码
     * @return 用户信息
     */
    public List<Map<String, Object>> findUserByRoleCode(String roleCode) {
        return userRepository.findUsersByRoleCode(roleCode);
    }

    /**
     * 根据用户编号查找用户
     *
     * @param userId 用户编号
     * @return 用户
     */
    public UserVo findUserByUserId(Long userId) {
        UserVo userVo = null;
        User user = userRepository.findUserById(userId);
        if (user != null) {
            userVo = new UserVo();
            BeanUtils.copyProperties(user, userVo);
        }
        return userVo;
    }

    /**
     * 添加用户
     *
     * @param userVo 用户
     * @return 用户编号
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addUser(UserVo userVo) {
        if (userRepository.findByAccountAndIsDel(userVo.getAccount(), false) != null) {
            return null;
        }
        User user = new User();
        RoleAccess roleAccess = new RoleAccess();

        roleAccess.setId(snowflakeIdWorker.nextId());
        roleAccess.setCreateAt(new Date());
        roleAccess.setCreateBy(1L);
        roleAccess.setUpdateAt(new Date());
        roleAccess.setUpdateBy(1L);

        userVo.setPassword(Md5.getMd5(userVo.getPassword()));
        BeanUtils.copyProperties(userVo, user);
        user.setId(snowflakeIdWorker.nextId());
        user.setCreateAt(new Date());
        user.setCreateBy(1L);
        user.setUpdateAt(new Date());
        user.setUpdateBy(1L);
        userRepository.save(user);

        roleAccess.setUserId(user.getId());
        roleAccess.setRoleCode(userVo.getRoleCode());
        roleAccessRepository.save(roleAccess);

        return user.getId();
    }

    /**
     * 修改用户信息
     *
     * @param userVo 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UserVo userVo) {
        User user = userRepository.findUserById(userVo.getId());
        BeanUtils.copyProperties(userVo, user);
        user.setUpdateBy(1L);
        user.setUpdateAt(new Date());

        RoleAccess roleAccess = roleAccessRepository.findRoleAccessByUserIdAndIsDel(userVo.getId(), false);
        roleAccess.setRoleCode(userVo.getRoleCode());
        RoleAccessVo roleAccessVo = new RoleAccessVo();
        BeanUtils.copyProperties(roleAccess, roleAccessVo);
        roleAccessService.updateRoleAccess(roleAccessVo);

        userRepository.save(user);
    }

    /**
     * 修改用户信息
     *
     * @param userVo 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRealUser(UserVo userVo) {
        User user = userRepository.findUserById(userVo.getId());
        BeanUtils.copyProperties(userVo, user);
        user.setUpdateBy(1L);
        user.setUpdateAt(new Date());
        userRepository.save(user);
    }

    /**
     * 根据账号和手机确认用户
     *
     * @param account 账号
     * @param phone   手机
     * @return 用户
     */
    public UserVo findByAccountAndPhone(String account, String phone) {
        UserVo userVo = new UserVo();
        User user = userRepository.findByAccountAndPhoneAndIsDel(account, phone, false);
        if (user != null) {
            BeanUtils.copyProperties(user, userVo);
        }
        return userVo;
    }

    /**
     * 根据用户编号查询预定信息
     *
     * @param userId     用户编号
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 预定信息
     */
    public PageResult<Map<String, Object>> findReserveMsgByUserId(Long userId, Integer pageNumber, Integer pageSize) {
        Page<Map<String, Object>> page = userRepository.findReserveMsgByUserId(userId, PageRequest.of(pageNumber, pageSize));
        return new PageResult<>(pageNumber, pageSize, page.getTotalPages(), page.getContent());
    }

    /**
     * 根据用户编号删除用户
     *
     * @param userId 用户编号
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserById(Long userId) {
        userRepository.deleteById(userId);
    }

    /**
     * 根据账号密码登录
     *
     * @param account  账号
     * @param password 密码
     * @return 用户id和角色代码
     */
    public RoleAccessVo login(String account, String password) {
        Long userId = this.getUserIdByAccountAndPassword(account, Md5.getMd5(password));
        if (userId == -1) {
            return null;
        }
        RoleAccessVo roleAccessVo = roleAccessService.getRoleAccessByUserId(userId);
        return roleAccessVo;
    }

    /**
     * 根据账号和手机号码判断是否存在该用户
     *
     * @param account 账号
     * @param phone   手机号码
     * @return 响应信息
     */
    public Map<String, Object> findUser(String account, String phone) {
        UserVo userVo = this.findByAccountAndPhone(account, phone);
        Boolean isExist = (userVo.getAccount() == null) ? false : true;
        Map<String, Object> map = new HashMap<>(16);
        map.put("isExist", isExist);
        map.put("userId", userVo.getId());
        return map;
    }

    /**
     * 根据用户id获取用户手机号码
     *
     * @param userId 用户id
     * @return 手机号码
     */
    public Map<String, String> getPhoneByUserId(Long userId) {
        UserVo userVo = this.findUserByUserId(userId);
        String phone = userVo.getPhone();
        Map<String, String> map = new HashMap<>(16);
        map.put("phone", phone);
        return map;
    }

    /**
     * 传入用户id和新密码，然后修改用户的密码
     *
     * @param userId   用户id
     * @param password 新密码
     * @return 响应信息
     */
    public void changePassword(Long userId, String password) {
        UserVo userVo = this.findUserByUserId(userId);
        userVo.setPassword(Md5.getMd5(password));
        this.updateRealUser(userVo);
    }

    /**
     * 传入用户id和新手机号码，然后修改用户的手机号码
     *
     * @param userId 用户id
     * @param phone  新密码
     */
    public void changePhone(Long userId, String phone) {
        UserVo userVo = this.findUserByUserId(userId);
        userVo.setPhone(phone);
        this.updateRealUser(userVo);
    }

}
